package com.van.bo.badwrting.edit.service.impl;


import com.fasterxml.jackson.core.type.TypeReference;
import com.van.bo.badwrting.edit.dao.DataDao;
import com.van.bo.badwrting.edit.domain.JavaDataInES;
import com.van.bo.badwrting.edit.domain.ParamData;
import com.van.bo.badwrting.edit.service.DataService;
import com.van.bo.badwrting.util.JsonMapper;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class DataServiceImpl implements DataService {

    @Resource
    private RestHighLevelClient highLevelClient;
    @Resource
    private DataDao dataDao;

    @Override
    public JavaDataInES saveData(JavaDataInES ji) {
        return dataDao.save(ji);
    }

    public JavaDataInES update(JavaDataInES ji) {
        return dataDao.save(ji);
    }

    @Override

    public JavaDataInES findById(String id) {
        return dataDao.findById(id).orElse(new JavaDataInES());
    }

    @Override
    public void deleteById(JavaDataInES data) {
        dataDao.delete(data);
    }

    @Override
    public List<JavaDataInES> findJavaDataList(ParamData pd) {

        if (StringUtils.isAllEmpty(pd.getSearch())) {
            PageRequest pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "createTime"));
            Page<JavaDataInES> all = dataDao.findAll(pageable);
            return all.get().collect(Collectors.toList());
        }

//        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//        boolQuery.must(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("channel", "hello")).minimumShouldMatch("100%"));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //构造一个默认配置的对象

//        sourceBuilder.query(QueryBuilders.multiMatchQuery(pd.getSearch(), "data", "desc", "other").minimumShouldMatch("100%")) //设置查询
        sourceBuilder.query(QueryBuilders.multiMatchQuery(pd.getSearch(), "data", "desc", "other")) //设置查询
                .from(pd.getPageIndex()) //设置从哪里开始
                .size(pd.getPageSize())


        ; //每页5条

        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); //设置超时时间
        SearchRequest searchRequest = new SearchRequest(JavaDataInES.class.getAnnotation(Document.class).indexName());// 不添加索引，搜索全部索引？
        searchRequest.source(sourceBuilder);
        try {
            SearchResponse search = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            List<JavaDataInES> dataList = new ArrayList<>();
            for (SearchHit sh : search.getHits()) {
                Map<String, Object> sourceAsMap = sh.getSourceAsMap();
                long version = sh.getVersion();
                JavaDataInES jd = JsonMapper.getJsonMapper().convertValue(sourceAsMap, JavaDataInES.class);
                jd.setId(sh.getId());
                jd.setDataVersion(version);
                dataList.add(jd);


            }
            return dataList;
        } catch (IOException e) {
            throw new RuntimeException("failed to search data!");
        }


    }

    //    @Override
    public List<JavaDataInES> boolQuery(JavaDataInES jd, ParamData pd) {


        //当天的时间，就不做查询了

        Map<String, Object> data = JsonMapper.getJsonMapper().convertValue(jd, new TypeReference<Map<String, Object>>() {
        });

        if (StringUtils.isAllEmpty(pd.getSearch())) {
            PageRequest pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "createTime"));
            Page<JavaDataInES> all = dataDao.findAll(pageable);
            return all.get().collect(Collectors.toList());
        }

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //构造一个默认配置的对象
        BoolQueryBuilder query = QueryBuilders.boolQuery();


        for (Map.Entry<String, Object> en : data.entrySet()) {
            query.must(QueryBuilders.matchQuery(en.getKey(), en.getValue()));
        }
        sourceBuilder.query(query)
                .from(pd.getPageIndex()) //设置从哪里开始
                .size(pd.getPageSize()); //每页5条
        sourceBuilder.timeout(new TimeValue(20, TimeUnit.SECONDS)); //设置超时时间
        SearchRequest searchRequest = new SearchRequest(JavaDataInES.class.getAnnotation(Document.class).indexName());// 不添加索引，搜索全部索引？
        searchRequest.source(sourceBuilder);
        try {
            SearchResponse search = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            List<JavaDataInES> dataList = new ArrayList<>();
            for (SearchHit sh : search.getHits()) {
                Map<String, Object> sourceAsMap = sh.getSourceAsMap();
                long version = sh.getVersion();
                JavaDataInES jdie = JsonMapper.getJsonMapper().convertValue(sourceAsMap, JavaDataInES.class);
                jdie.setId(sh.getId());
                jdie.setDataVersion(version);
                dataList.add(jdie);
            }
            return dataList;
        } catch (IOException e) {
            throw new RuntimeException("failed to search data!");
        }
    }

}
